package cn.siat.gene.util;

import cn.siat.common.core.exception.base.BaseException;
import cn.siat.common.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;

import java.io.*;
import java.nio.charset.Charset;

/**
 * CmdUtil
 *
 * @author zhanggj@hearglobal.com
 * @version 0.0.1
 * @date 2022.12.01
 */
@Slf4j
public class CmdUtil {

    public void test() {
//        String predictionPath = "C:\\Users\\zgj\\Desktop\\3\\0\\gRNA_Prediction_v20220728\\bin\\gRNA_Prediction.exe -c C:\\Users\\zgj\\Desktop\\3\\0\\";
//
//        String s = execCmdOrder("gRNA.conf");
        String cofigFilePath = "D:\\test\\2022-12-05\\1670217882966_gRNA.conf";
        String outFilePath = "D:\\test\\2022-12-05\\2022-12-05";
        String zipPath = "D:\\test\\2022-12-05";
        String zipName = "zipName";
        String s = compressGrna(cofigFilePath, outFilePath, zipPath, zipName);
        System.out.println(s);

    }

    public static String execCmdOrder(String cmdCommand) {

        if (StringUtils.isEmpty(cmdCommand)) {
            throw new RuntimeException("需要执行的conf不可以为空");
        }

        //组装cmd 命令
        String cmd = "cmd /C " + cmdCommand;
//        BufferedReader br = null;
        Process process = null;
        //执行命令结果
        StringBuilder result = null;
        try {
            //执行cmd命令
            process = Runtime.getRuntime().exec(cmd);
            process.waitFor();
            //获取cmd命令的输出结果
//            br = new BufferedReader(new InputStreamReader(process.getInputStream(), Charset.forName("GBK")));
//            result = new StringBuilder();
//            String tmp;
            //组装命令执行结束后返回值
//            while ((tmp = br.readLine()) != null) {
//                result.append(tmp).append("\n");
//                System.out.println(tmp);
//            }
        } catch (InterruptedException | IOException e) {
            log.error(e.getMessage());
        } finally {
//            if (br != null) {
//                try {
//                    br.close();
//                } catch (IOException e) {
//                    log.error(e.getMessage());
//                }
//            }
            if (process != null) {
                process.destroy();
            }
        }
        return result.toString();
    }


    public static String callCmd(String cmdCommand) throws InterruptedException  {
        if (StringUtils.isEmpty(cmdCommand)) {
            throw new RuntimeException("需要执行的conf不可以为空");
        }

        //组装cmd 命令
        String cmd = "cmd /C " + cmdCommand;
        Process process = null;
        BufferedReader normalReader = null;
        BufferedReader errorReader = null;
        try {

            process = Runtime.getRuntime().exec(cmd);

                /*
                    启动读取buffer缓冲区子线程,避免buffer缓冲区被写满,导致线程等待问题
                 */
            normalReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            errorReader = new  BufferedReader(new  InputStreamReader(process.getErrorStream()));

            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = normalReader.readLine()) != null) {
                sb.append(line+"\n");
            }
            String errorLine;
            while ((errorLine = errorReader.readLine()) != null) {
                System.out.print("脚本文件执行信息ErrorStream:{}"+ errorLine+"\n");
            }
            // 等待程序执行结束并输出状态
            int exitCode = process.waitFor();

            if (0 == exitCode) {
                System.out.print("脚本文件执行成功");

            } else {
                System.out.print("脚本文件执行失败:{}"+cmd);

                throw new BaseException("脚本文件执行失败:"+cmd);
            }
            return sb.toString();
        } catch (java.lang.NullPointerException e) {
            throw new BaseException(e);
        } catch (java.io.IOException e) {
            throw new BaseException(e);
        }finally{
            if (null != normalReader) {
                try {
                    normalReader.close();
                } catch (IOException e) {
                    System.out.print("流文件关闭异常："+ e);
                }
            }
            if (null != errorReader) {
                try {
                    errorReader.close();
                } catch (IOException e) {
                    System.out.print("流文件关闭异常："+ e);
                }
            }
            if (null != process) {
                process.destroy();
            }
        }
    }

    public static String execute(String command) {
        BufferedReader bufferedReader = null;
        StringBuilder stringBuilder = new StringBuilder();
        String result = null;
        try {
            File file = new File("D:\\daemonTmp");
            // 新建一个存储结果的缓存文件
            File tmpFile = new File("D:\\daemonTmp\\temp.tmp");
            if (!file.exists()) {
                file.mkdirs();
            }
            if (!tmpFile.exists()) {
                tmpFile.createNewFile();
            }
            ProcessBuilder processBuilder = new ProcessBuilder()
                    .command("cmd.exe", "/c", command).inheritIO();
            // 把控制台中的红字变成了黑字，用通常的方法其实获取不到，控制台的结果是pb.start()方法内部输出的。
            processBuilder.redirectErrorStream(true);
            // 输出执行结果。
            processBuilder.redirectOutput(tmpFile);
            // 等待语句执行完成，否则可能会读不到结果。
            processBuilder.start().waitFor();
            InputStream inputStream = new FileInputStream(tmpFile);
            //设置编码
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
            String line = null;
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line + "\n");
            }
            bufferedReader.close();
            bufferedReader = null;

            result = stringBuilder.toString();

        } catch(Exception e) {
            log.error(e.getMessage());
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch(IOException e) {
                    log.error(e.getMessage());
                }
            }
        }
        return result;
    }

    /**
     * 压缩 gRNA_Prediction
     *
     * @param cofigFilePath conf路径
     * @param outFilePath 需要压缩路径
     * @param zipPath 压缩之后文件名称
     * @param zipPath 压缩之后输出路径
     * @author zhanggj@hearglobal.com
     * @date 2022.12.5 13:18
     * @version 0.0.1
     */
    public static String compressGrna(String cofigFilePath, String outFilePath, String zipPath, String zipNamo) {
        if(cofigFilePath.equals("cofigFilePath")){

        }else {
            copyFile(cofigFilePath,outFilePath + "/input");
        }
        //复制文件


        OutputStream fileOutputStream = null;
        try {
            //Navicat路径
            //打包后输出路径
//            String substring = zipPath.substring(0,zipPath.lastIndexOf("\\") + 1);
            String substring =zipPath;
            String outDir = substring + "\\" + zipNamo + ".zip";
            fileOutputStream = new FileOutputStream(new File(outDir));
//            GbffUtil.toZip(outFilePath, fileOutputStream, true);
            System.out.print("删除输出文件夹");
//            GbffUtil.deleteAllFile(outFilePath);
            return outDir;
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * 复制文件或者目录,复制前后文件完全一样。
     * @param resFilePath   源文件路径
     * @param distFolder    目标文件夹
     * @IOException         当操作发生异常时抛出
     */
    public static void copyFile(String resFilePath, String distFolder){

        try {
            File resFile = new File(resFilePath);

            File distFile = new File(distFolder);

            if (resFile.isDirectory()) { // 目录时

                FileUtils.copyDirectoryToDirectory(resFile, distFile);

            } else if (resFile.isFile()) { // 文件时

                FileUtils.copyFileToDirectory(resFile, distFile);

            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }

    }
}
